#ifndef GML__VECTOR_H
#define GML__VECTOR_H

#include <stdbool.h>
#include <stddef.h>

#define VectorType(_Type) Vector##_Type

#define VectorFunc(_Func) vector##_Func

#define VectorAlgo(_Algo) _Algo##RandomAccess

typedef int *VectorIterator;

typedef const int *VectorConstIterator;

bool vectorIteratorEqualTo(const VectorIterator *_this, const VectorIterator *_vectorIterator);

bool vectorIteratorNotEqualTo(const VectorIterator *_this, const VectorIterator *_vectorIterator);

bool vectorIteratorLessThan(const VectorIterator *_this, const VectorIterator *_vectorIterator);

int *vectorIteratorIndirect(const VectorIterator *_this);

int *vectorIteratorSubscript(const VectorIterator *_this, ptrdiff_t _n);

VectorIterator *vectorIteratorIncreasePrefix(VectorIterator *_this);

VectorIterator vectorIteratorIncreasePostfix(VectorIterator *_this);

VectorIterator *vectorIteratorDecreasePrefix(VectorIterator *_this);

VectorIterator vectorIteratorDecreasePostfix(VectorIterator *_this);

VectorIterator *vectorIteratorAddAssign(VectorIterator *_this, ptrdiff_t _n);

VectorIterator vectorIteratorAdd(const VectorIterator *_this, ptrdiff_t _n);

VectorIterator *vectorIteratorSubtractAssign(VectorIterator *_this, ptrdiff_t _n);

VectorIterator vectorIteratorSubtract(const VectorIterator *_this, ptrdiff_t _n);

ptrdiff_t vectorIteratorDiff(const VectorIterator *_this, const VectorIterator *_vectorIterator);

typedef struct Vector {
	VectorIterator begin_;
	VectorIterator end_;
	VectorIterator endOfStorage_;
} Vector;

Vector *vectorNew();

void vectorDelete(Vector *_this);

void vectorConstruct(Vector *_this);

void vectorDestruct(Vector *_this);

int *vectorSubscript(Vector *_this, ptrdiff_t _n);

const int *vectorSubscriptConst(const Vector *_this, ptrdiff_t _n);

VectorIterator vectorBegin(Vector *_this);

VectorConstIterator vectorBeginConst(const Vector *_this);

VectorIterator vectorEnd(Vector *_this);

VectorConstIterator vectorEndConst(const Vector *_this);

VectorIterator vectorInsert(Vector *_this, VectorIterator _position, int _value);

VectorIterator vectorInsertN(Vector *_this, VectorIterator _position, size_t _n, int _value);

VectorIterator vectorInsertIn(Vector *_this, VectorIterator _position, VectorIterator _first, VectorIterator _last);

void vectorErase(Vector *_this, VectorIterator _position);

void vectorEraseN(Vector *_this, VectorIterator _position, size_t _n);

void vectorEraseIn(Vector *_this, VectorIterator _first, VectorIterator _last);

bool vectorEmpty(const Vector *_this);

size_t vectorCapacity(const Vector *_this);

size_t vectorSize(const Vector *_this);

void vectorClear(Vector *_this);

void vectorResize(Vector *_this, size_t _n);

void vectorSort(VectorIterator _first, VectorIterator _last);

#endif // GML__VECTOR_H
